home *** CD-ROM | disk | FTP | other *** search
/ Floppyshop 2 / Floppyshop - 2.zip / Floppyshop - 2.iso / diskmags / 5791-.end / dmg-6143 / lza_rept / compres2.txt < prev    next >
Text File  |  1995-05-29  |  17KB  |  332 lines

  1.                Experiments in Data Compression II
  2.        (or "Why couldn't I have thought of this sooner?")
  3.                          by John Kormylo
  4.                          E.L.F. Software
  5.  
  6.  
  7. State of the Art
  8.  
  9.      In the following table are shown the results for compressing 
  10. three  different  files using  three  different  methods.   'ZIP' 
  11. refers  to STZIP 2.5 (deflating).   'OLD' refers to the  improved 
  12. LZA  method documented in the previous report using a single  16K 
  13. search  tree.    'BEST'  refers  to  the  best  results  obtained 
  14. previously,  using  three search trees and testing  all  possible 
  15. ways to compress the next 65 characters.
  16.  
  17.  
  18.        | DEMONSTR.DOC | ELFBACK.PRG | WORDLIST.TXT |
  19. -------+--------------+-------------+--------------+
  20.    ZIP |       25207  |      32444  |      496880  |
  21.    OLD |       24942  |      34003  |      670774  |
  22.   BEST |       22196  |      32035  |      455017  |
  23. -------+--------------+-------------+--------------+
  24.  
  25.  
  26. Redundancy Weighting
  27.  
  28.      The  main inefficiency of the old LZA method is  that  while 
  29. there can be many matches of a given length, only one can be used 
  30. at  a time.   No matter how heavily the entry used  is  weighted, 
  31. there is still lost information in the other possible matches.
  32.      Using a hash table instead of a search tree could solve this 
  33. problem,  but  hash  tables are inefficient for  storage  (a  16K 
  34. binary  search tree with a maximum match length of 65  characters 
  35. would  require up to 1,054,960 entries in a hash  table).   Also, 
  36. once something is put into a hash table it can never be taken out 
  37. again (at least, using the implementation documented in "The Data 
  38. Compression Book" by Mark Nelson).
  39.      However,   since   the  binary  search  tree   has   already 
  40. alphabetized  the  "dictionary"  of  possible  matches,   it   is 
  41. relatively easy to use an index corresponding to its position  in 
  42. alphabetical order.   This can be done easily by including in the 
  43. node  structure  a  count of how many nodes are  in  this  branch 
  44. (actually, the self-balancing functions already require this).
  45.      More  important,  it is also easy to locate the largest  and 
  46. smallest indexes corresponding to a match of a given length  (and 
  47. certainly  faster  than searching for the most  heavily  weighted 
  48. match).  The 'weight' for this 'match' is therefore the number of 
  49. matches for this length in the search tree (as it turns out,  the 
  50. arithmetic compression algorithm normally implements weights as a 
  51. range of index values).   The length (and match indicator)  codes 
  52. are implemented using character codes 256 through 320, as before.
  53.      When  expanding  the data,  one will get some value  in  the 
  54. range  of possible matches.   One would then search  through  the 
  55. binary tree to locate the specific dictionary entry.   Given  the 
  56. text pointer from this node,  one can then go through the  search 
  57. tree  again and locate the largest and smallest matches for  this 
  58. length.
  59.      Obviously, this approach is more efficient than any possible 
  60. weighting scheme involving single dictionary entries.  Also, this 
  61. approach is relatively insensitive to dictionary size,  since the 
  62. number  of matches should increase proportionately as the  number 
  63. of entries increase (assuming a uniformly random distribution  of 
  64. matches).   Other advantages are that the node structure does not 
  65. need to store the weight,  last match length or sort  index,  and 
  66. that one need not sort the indexes into weight order.
  67.      The  main disadvantage is that the expansion algorithm  must 
  68. also sort the entries into a binary search tree.   Not only  does 
  69. this make the expansion slower,  it requires that the compression 
  70. algorithm not use information not yet coded when constructing the 
  71. search tree.  Normally, the compression algorithm uses all 65 (or 
  72. whatever the maximum match length is) future characters to  place 
  73. a  text pointer into the tree.   Needless to say,  the  expansion 
  74. algorithm does not have access to these future characters.
  75.      Another disadvantage is that one cannot use this approach to 
  76. match  future  characters.   When the old LZA method ran  into  a 
  77. sequence of repeated characters (not yet in the  dictionary),  it 
  78. would  code the first normally and code the rest by matching  the 
  79. text pointer just entered into the tree.  The expansion algorithm 
  80. would recursively generate the entire sequence:
  81.  
  82.      for(i=0; i<len; i++) text[i+1] = text[i];
  83.  
  84.  
  85. Backwards Matching
  86.  
  87.      Instead  of sorting strings in alphabetical order from  left 
  88. to right,  one could sort strings from right to left.  The search 
  89. tree  would  then  consist of pointers to the  ENDS  of  matches, 
  90. rather than the STARTS of matches.  Obviously, this approach does 
  91. not  use  future characters,  so the  compression  and  expansion 
  92. algorithms will automatically keep in step.
  93.      The  disadvantage is that instead of searching  through  the 
  94. tree  for the longest match at a given start location,  one  must 
  95. search  through  the tree for a match of a known  length  for  65 
  96. possible  ending  locations.    (Actually,   one  can  save  this 
  97. information  from one step to the next,  but it still requires  a 
  98. search for every byte in the message instead of only those  bytes 
  99. not skipped.)  This approach is slower than 'OLD' but much faster 
  100. than 'BEST'.
  101.      The  following  table shows the results  using  the  longest 
  102. match  (as  'LONG'),  using the match with the  fewest  bits  per 
  103. character (as 'AVG') and searching all possible ways to  compress 
  104. the next 65 bytes (as 'BEST' again).
  105.  
  106.  
  107.        | DEMONSTR.DOC | ELFBACK.PRG | WORDLIST.TXT |
  108. -------+--------------+-------------+--------------+
  109.   LONG |       23322  |      34362  |      649317  |
  110.    AVG |       23043  |      34693  |      660107  |
  111.   BEST |       22007  |      33276  |      580261  |
  112. -------+--------------+-------------+--------------+
  113.  
  114.  
  115. These  results were somewhat disappointing.   While  new  records 
  116. were  set  for  DEMONSTR.DOC,  this  method  seems  fundamentally 
  117. incapable of performing well on the other two files.  (All of the 
  118. above results were for a 16K search tree.)
  119.      The next table shows the results from using the above  'AVG' 
  120. method for various tree sizes.  The results (as compared to those 
  121. in  the  previous  report) for DEMONSTR.DOC are  what  should  be 
  122. expected when the statistical assumptions (uniformly  distributed 
  123. matches)  are  satisfied:  decreasing effectiveness as  the  tree 
  124. size decreases and slightly better compression for all tree sizes 
  125. (above  256).   The results for WORDLIST.TXT are what  should  be 
  126. expected  when matches tend to be locally  clustered:  increasing 
  127. effectiveness  as  the tree size decreases (up to  a  point)  and 
  128. slightly better results (for tree sizes above 512).   The results 
  129. for  ELFBACK.PRG possibly indicate a lot of  repeated  sequences: 
  130. less effectiveness for all tree sizes.
  131.  
  132.   tree | DEMONSTR.DOC | ELFBACK.PRG | WORDLIST.TXT |
  133. -------+--------------+-------------+--------------+
  134.     32 |       45008  |      45812  |      544218  |
  135.     64 |       42188  |      43799  |  >   536383  |
  136.    128 |       38167  |      41574  |      538023  |
  137.    256 |       34187  |      39331  |      548685  |
  138.    512 |       31076  |      37480  |      564429  |
  139.   1024 |       27844  |      36567  |      581900  |
  140.   2048 |       25690  |      35234  |      601221  |
  141.   4096 |       24088  |      34728  |      624977  |
  142.   8192 |       23235  |  >   34571  |      644742  |
  143.  16384 |  >    23043  |      34693  |      660107  |
  144.  
  145.  
  146. FIFO Buffer
  147.  
  148.      An alternative solution is to not add match locations to the 
  149. search tree until all 65 characters have been coded.  This can be 
  150. implemented using a 64 entry FIFO (First In/ First Out) buffer to 
  151. hold these new locations.  In fact, one can use this buffer as an 
  152. alternative  search  tree,  similar to the multiple  search  tree 
  153. methods  explored  in  the previous  report.   This  should  also 
  154. improve performance on files with locally clustered matches.
  155.      The  following  table shows the results  for  this  approach 
  156. using a 64 entry tree (unweighted) and a 16K entry tree (weighted 
  157. by  the number of matches).   Again,  using the longest match  is 
  158. labeled as 'LONG',  using the fewest bits/character is labeled as 
  159. 'AVG', and using the (nearly) optimal selections as 'BEST'.
  160.  
  161.  
  162.        | DEMONSTR.DOC | ELFBACK.PRG | WORDLIST.TXT |
  163. -------+--------------+-------------+--------------+
  164.   LONG |       24618  |      33418  |      597383  |
  165.    AVG |       23991  |      33269  |      555619  |
  166.   BEST |       21893  |      32147  |      496517  |
  167. -------+--------------+-------------+--------------+
  168.  
  169. Both the LONG and AVG algorithms out-performed the OLD  algorithm 
  170. on all three files.   However,  the new BEST algorithm  performed 
  171. better on only one of the files.
  172.      It  should be noted that entries in the FIFO buffer  can  be 
  173. flushed  to  the  main dictionary as soon as  all  65  bytes  are 
  174. transmitted,  effectively  reducing the size of the FIFO  buffer.  
  175. However,  as shown in the next table,  this doesn't buy you much.  
  176. In fact, it is worse on two of the three files:
  177.  
  178.  
  179.        | DEMONSTR.DOC | ELFBACK.PRG | WORDLIST.TXT |
  180. -------+--------------+-------------+--------------+
  181.   LONG |       24630  |      33544  |      599469  |
  182.    AVG |       24082  |      33466  |      540713  |
  183.   BEST |       22034  |      32345  |      473610  |
  184. -------+--------------+-------------+--------------+
  185.  
  186.  
  187. On  the  other hand,  increasing the FIFO buffer to  128  entries 
  188. doesn't help either.
  189.  
  190.  
  191. FIFO Weighting
  192.  
  193.      The  reason  the  FIFO buffer  approach  works  better  than 
  194. backwards sorting is that the statistical assumption of a uniform 
  195. random distribution of matches is not valid for some  files.   In 
  196. this case the probabilty of finding a match in the 64 entry  FIFO 
  197. buffer is much greater than the number of equilvalent matches  in 
  198. the main dictionary divided by the total number of entries.
  199.      That being the case,  it would also seem reasonable that the 
  200. probability  of  finding a match in the most recent half  of  the 
  201. FIFO buffer is greater than in the older half,  etc.   One  could 
  202. assign  a  weight associated with each entry in the  FIFO  buffer 
  203. based on how long it has been there,  and use those weights  when 
  204. coding the index.   These weights would,  of course,  consist  of 
  205. (scaled)  counts  of  how many times this  'lag'  has  been  used 
  206. (initially  set to 1).   Since there are only  64  entries,  this 
  207. should not impose much additional computation cost.
  208.      The next table shows the results for using these weights for 
  209. the FIFO buffer:
  210.  
  211.  
  212.        | DEMONSTR.DOC | ELFBACK.PRG | WORDLIST.TXT |
  213. -------+--------------+-------------+--------------+
  214.   LONG |       24620  |      33375  |      583218  |
  215.    AVG |       23991  |      33207  |      530798  |
  216.   BEST |       22022  |      32088  |      461457  |
  217. -------+--------------+-------------+--------------+
  218.  
  219. As   expected,   these  results  were  not  quite  as  good   for 
  220. DEMONSTR.DOC,  but better for the other two files.  A list of the 
  221. weights  generated  using  the 'AVG' approach  is  shown  in  the 
  222. Appendix.   (It  should be pointed out that this is not  strictly 
  223. speaking a 'lag' in the time series sense,  since each  increment 
  224. can mean anywhere from 1 to 65 bytes.)
  225.  
  226.  
  227. Break Even
  228.  
  229.      Another advantage of redundancy weighting is that it does  a 
  230. much  better job for smaller matches.   (One could  theoretically 
  231. use  it for single characters,  except that you would still  need 
  232. some way to get the dictionary started.)  However,  early testing 
  233. indicated  that  the best results were obtained  by  never  using 
  234. matches  of  length 2 and always using matches of  length  3  (as 
  235. opposed  to  testing for break even as was done using  the  'OLD' 
  236. LZA algorithm.)
  237.      The  next table show the results of using length  2  matches 
  238. with FIFO weighting:
  239.  
  240.  
  241.        | DEMONSTR.DOC | ELFBACK.PRG | WORDLIST.TXT |
  242. -------+--------------+-------------+--------------+
  243.   LONG |       24860  |      34719  |      585185  |
  244.    AVG |       24054  |      34394  |      520875  |
  245.   BEST |       22029  |      31997  |      453143  |
  246. -------+--------------+-------------+--------------+
  247.  
  248.  
  249. Comparing  this  to the previous table,  we  see  that  including 
  250. length 2 matches only works well with the 'BEST' algorithm (which 
  251. implicitly contains a break even test).   More importantly,  this 
  252. allows the new 'BEST' to beat the old 'BEST' (in the first table) 
  253. on all three files.
  254.  
  255.  
  256.  
  257.  
  258.  
  259.       Appendix - Normalized Weights (count / total * 1000)
  260.  
  261.   lag  | DEMONSTR.DOC | ELFBACK.PRG | WORDLIST.TXT |
  262. -------+--------------+-------------+--------------+
  263.     1  |        3     |      21     |       12     |
  264.     2  |        5     |      63     |      251     |
  265.     3  |       14     |      23     |      109     |
  266.     4  |        8     |      66     |       88     |
  267.     5  |       18     |      33     |       59     |
  268.     6  |       24     |      37     |       48     |
  269.     7  |       13     |      24     |       35     |
  270.     8  |       19     |      42     |       31     |
  271.     9  |       21     |      28     |       26     |
  272.    10  |        8     |      35     |       23     |
  273.    11  |       21     |      22     |       19     |
  274.    12  |       20     |      26     |       16     |
  275.    13  |       33     |      20     |       15     |
  276.    14  |       24     |      24     |       13     |
  277.    15  |       21     |      18     |       13     |
  278.    16  |       19     |      17     |       12     |
  279.    17  |       26     |      18     |       10     |
  280.    18  |       25     |      16     |       10     |
  281.    19  |        9     |      18     |       10     |
  282.    20  |       25     |      15     |        9     |
  283.    21  |       15     |      18     |        8     |
  284.    22  |       17     |      17     |        8     |
  285.    23  |       14     |      18     |        7     |
  286.    24  |       28     |      15     |        7     |
  287.    25  |       22     |      13     |        7     |
  288.    26  |       17     |      13     |        6     |
  289.    27  |       23     |      20     |        6     |
  290.    28  |       16     |      15     |        6     |
  291.    29  |       17     |      14     |        6     |
  292.    30  |       17     |       9     |        5     |
  293.    31  |       18     |      14     |        6     |
  294.    32  |       14     |      11     |        5     |
  295.    33  |       34     |      11     |        5     |
  296.    34  |       12     |       8     |        5     |
  297.    35  |       26     |      12     |        5     |
  298.    36  |       13     |      10     |        4     |
  299.    37  |       17     |       9     |        5     |
  300.    38  |       17     |      13     |        5     |
  301.    39  |       20     |       7     |        4     |
  302.    40  |       13     |      10     |        4     |
  303.    41  |       16     |      10     |        4     |
  304.    42  |       11     |       9     |        4     |
  305.    43  |        9     |       7     |        4     |
  306.    44  |        9     |       8     |        4     |
  307.    45  |       15     |       3     |        4     |
  308.    46  |       13     |       4     |        3     |
  309.    47  |       18     |       8     |        3     |
  310.    48  |        7     |       9     |        3     |
  311.    49  |       14     |       5     |        3     |
  312.    50  |        9     |       9     |        3     |
  313. -------+--------------+-------------+--------------+
  314.   lag  | DEMONSTR.DOC | ELFBACK.PRG | WORDLIST.TXT |
  315. -------+--------------+-------------+--------------+
  316.    51  |       15     |       9     |        3     |
  317.    52  |       14     |       5     |        3     |
  318.    53  |       20     |       8     |        3     |
  319.    54  |        9     |       6     |        3     |
  320.    55  |        8     |       6     |        3     |
  321.    56  |        8     |       9     |        3     |
  322.    57  |       13     |       5     |        3     |
  323.    58  |       10     |      11     |        3     |
  324.    59  |        4     |      13     |        3     |
  325.    60  |       15     |       9     |        2     |
  326.    61  |       12     |       4     |        2     |
  327.    62  |        7     |       9     |        3     |
  328.    63  |        8     |       8     |        3     |
  329.    64  |        9     |       7     |        2     |
  330. -------+--------------+-------------+--------------+
  331.  
  332.